Міністерство освіти, науки, молоді та спорту України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
Звіт
до лабораторної роботи №2
на тему: «Змішане програмування на мовах С та Асемблер»
з предмету: «Системне програмування»
Підготувала:
ст.гр. КІ-33
Надолинська Ольга
Перевірив:
Олексів М.В.
Львів 2012
Мета: оволодіти навиками створення програм, частини яких написані різними мовами програмування Засвоїти правила взаємодії різних модулів.
ТЕОРЕТИЧНІ ВІДОМОСТІ
Труднощі опису зв'язку програм мовою C і асемблерних програм полягає в тому, що різні версії мови C мають різні угоди про зв'язки і для більш точної інформації варто користатися посібником з наявної версії мови C.
Більшість версій мови C забезпечують передачу параметрів через стек у зворотній (у порівнянні з іншими мовами) послідовності. Звичайно доступ, наприклад, до двох параметрів, переданих через стек, здійснюється в такий спосіб:
PUSH EBP
MOV EBP,ESP
MOV EAX,[EBP+8]
MOV EDX,[EBP+12]
...
POP EBP
RET
Деякі версії мови C розрізняють великі і малі букви, тому ім'я асемблерного модуля повинне бути представлено в тому ж символьному регістрі, який використовують для посилання C-програми.
У деяких версіях мови C потрібно, щоб асемблерні програми, що змінюють регістри EDI і ESI, записували їхній вміст у стек при вході і відновлювали ці значення зі стека при виході.
Ассемблерні програми повинні повертати значення, якщо це необхідно, у регістрі EAX (подвійне слово) чи в регістровій парі EDX:EAX (8 слів).
Для деяких версій мови C, якщо ассемблерна програма встановлює прапор DF, те вона повинна скинути його командою CLD перед поверненням.
Щоб скомпонувати разом модулі C++ і Макро асемблера, повинні бути дотримані наступні три умови:
У модулях Макро Асемблера повинні використовуватися угоди про імена, прийняті в C++.
C++ і Макро Асемблер повинні спільно використовувати відповідні функції й імена змінних у формі, прийнятної для C++.
Для комбінування модулів у виконувану програму потрібно використовувати утіліту-компоновщик (TLINK, LINK тощо).
Підкреслення і мова С
Якщо ви пишете мовою С чи С++, то всі зовнішні мітки повинні починатися із символу підкреслення (_). Компілятор С і С++ вставляє символи підкреслення перед всіма іменами зовнішніх функцій і змінних при їхньому використанні в програмі на С/С++ автоматично, тому вам потрібно вставити їх самим тільки в кодах асемблера. Ви повинні переконатися, що всі асемблерні звертання до функцій і змінних С починаються із символу підкреслення, і крім того, ви повинні вставити його перед іменами всіх асемблерних функцій і змінних, котрі робляться загальними і викликаються з програми мовою С/С++.
Наприклад, наступна програма мовою С (link2asm.cpp):
extrn int ToggleFlag();
int Flag;
main()
{
ToggleFlag();
}
правильно компонується з наступною програмою на Асемблері (CASMLINK.ASM):
.586
.MODEL FLAT
.DATA
EXTRN _Flag:dword
.CODE
PUBLIC _ToggleFlag
_ToggleFlag PROC
cmp [_Flag],0 ; прапор скинутий?
jz SetFlag ; так, установити його
mov [_Flag],0 ; ні, скинути його
jmp EndToggleFlag ; виконано
SetFlag:
mov [_Flag],1 ; установити прапор
EndToggleFlag:
ret
_ToggleFlag ENDP
END
При використанні в директивах EXTERN і PUBLIC специфікатора мови С правильно компонується з наступною програмою на Асемблері (CSPEC.ASM) (приклад для 16-ти бітної програми):
.MODEL Small
.DATA
EXTRN C Flag:word
.CODE
PUBLIC C ToggleFlag
ToggleFlag PROC
cmp [Flag],0 ; прапор скинутий?
jz SetFlag ; так, установити його
mov [Flag],0 ; ні, скинути його
jmp short EndToggleFlag ; виконано
SetFlag:
mov [Flag],1 ; установити прапор
EndToggleFlag:
ret
ToggleFlag ENDP
END
Розпізнавання рядкових і прописних символів в ідентифікаторах
В іменах ідентифікаторів Макро асемблер звичайно не розрізняє рядкові і прописні букви (верхній і нижній регістр). Оскільки в С++ вони розрізняються, ...